1. Field of the Invention
The present invention relates to computer instruction code. More specifically, the present invention relates to a method and an apparatus that facilitates sharing computer instruction code between programs in a multitasking virtual machine.
2. Related Art
Computer programs written in languages such as JAVA™are compiled into a platform-independent code, which is executed on a virtual machine, such as the JAVA VIRTUAL MACHINE (JVM). A program that has been compiled into a platform-independent code has the advantage that it can execute on a virtual machine regardless of the underlying central processing unit and native code. The terms JAVA, JVM and JAVA VIRTUAL MACHINE are trademarks of SUN Microsystems, Inc. of Palo Alto, Calif.
A virtual machine typically includes an interpreter, which interprets the platform-independent code into native code to perform the desired operations. Interpreting the platform-independent code is an inherently slow operation; therefore, many virtual machines also include a dynamic compiler, which can compile the platform-independent code at runtime into the native code of the machine being used to host the virtual machine. Compiling the platform-independent code into the native code of the host machine can reduce the execution time of the program.
Virtual machines for object-oriented programming languages with dynamic class loading typically load the code of a class when a program resolves a symbolic reference to that class for the first time. The class needs to be initialized subsequently when the program uses it for the first time. Loading and initialization of a class are two separate events. Initialization of a class may never take place even though the class has been loaded. In the case of the Java programming language, the initialization of a class consists of executing some code, known as the class's static initializer, that brings the class's variables (also known as the static variables) to a well-defined initialized state. A virtual machine implementation may choose to set a class to the initialized state upon loading when no action is required to initialize that class. For instance, in the Java programming language, no action is required to initialize a class when this class has no declared static initialization sequence, and either no non-final static variables, or non-final static variables that are all declared to be set to a default value. In this case, a virtual machine implementation can benefit from setting such initialization-less classes to the initialized state upon class loading.
A class initialization barrier is a sequence of native instructions that calls the virtual machine's runtime to initialize a class if it is not already initialized. Class initialization barriers are included in the implementation of those platform-independent instructions that may result in the very first use of a class (in the case of the Java programming language, there are 4 such instructions: getstatic, putstatic, invokestatic, new). The implementation of a platform-independent instruction can come in two flavors: (i) as a sequence of instructions that is part of the implementation of an interpreter of platform-independent instructions, (ii) or as a sequence of instruction generated by a dynamic compiler of platform-independent instructions.
Because class initialization barriers need only to be executed once per class, it is common practice in the implementation of non-multitasking virtual machines to have recourse to code-rewriting techniques to remove the class initialization barriers and the overhead they induce. In other words, a class initialization barrier can simply be an instruction that calls the virtual machine runtime and that is removed, or replaced, by the runtime before returning to the call site.
A multitasking virtual machine (MVM) aims at saving processing and memory by sharing as much of the runtime representation of a class as possible among tasks executing programs that use the class. Targets for sharing include the meta-data describing the class, the platform-independent code of the class's methods, and the native code produced by the dynamic compiler. Code re-writing techniques can be harmful when code, whether it is platform-independent or produced by a runtime compiler, is shared between multiple tasks. For instance, rewriting native code to remove a class initialization barrier is incorrect when that code is shared between multiple tasks, since tasks that have not initialized the corresponding class may subsequently be given access to that class without the class being initialized first. Task re-entrant class initialization barriers that test the initialization state of a class for the current task must be used instead. However, these barriers may result in severe performance penalty, in particular, by preventing some useful optimization, such as method inlining.
What is needed is a method and an apparatus that provides the benefits of sharing dynamically compiled native code among tasks of a multitasking virtual machine while eliminating the overhead resulting from the use of task re-entrant class initialization barriers.